﻿//#include <iostream>
//#include <string>
//#include <cmath> // 用于 fmin 函数
//using namespace std/*;*/

//int main()
//{
//    // 左值：可以取地址
//    // 以下的p、b、c、*p、s、s[0]就是常见的左值
//    int* p = new int(0);
//    int b = 1;
//    const int c = b;
//    *p = 10;
//    string s("111111");
//    s[0] = 'x';
//
//    cout << "左值地址示例：" << endl;
//    cout << "p 的地址: " << &p << endl;
//    cout << "b 的地址: " << &b << endl;
//    cout << "c 的地址: " << &c << endl;
//    cout << "*p 的值: " << *p << endl;
//    cout << "s: " << s << endl;
//    cout << "s[0] 的地址: " << (void*)&s[0] << endl;
//    cout << endl;
//
//    // 右值：不能取地址
//    double x = 1.1, y = 2.2;
//    // 以下几个10、x + y、fmin(x, y)、string("11111")都是常见的右值
//
//    cout << "右值示例：" << endl;
//    cout << "10: " << 10 << endl;
//    cout << "x + y: " << x + y << endl;
//    cout << "fmin(x, y): " << fmin(x, y) << endl;
//    cout << "string(\"11111\"): " << string("11111") << endl;
//    cout << endl;
//
//    // 以下代码会编译错误，因为不能取右值的地址
//     cout << &10 << endl;
//     cout << &(x+y) << endl;
//     cout << &(fmin(x, y)) << endl;
//     cout << &string("11111") << endl;
//
//
//    return 0;
//}

//
//#include <iostream>
//#include <string>
//#include <cmath> // 用于 fmin 函数
//using namespace std;
//
//int main() {
//    int b = 10;
//    int* p = &b;
//    string s = "Hello";
//
//    // 左值引用给左值取别名
//    int& r1 = b;
//    int*& r2 = p;
//    int& r3 = *p;
//    string& r4 = s;
//    char& r5 = s[0];
//
//    double x = 1.1, y = 2.2;
//
//    // 右值引用给右值取别名
//    int&& rr1 = 10;
//    double&& rr2 = x + y;
//    double&& rr3 = fmin(x, y);
//    string&& rr4 = string("11111");
//
//    // 左值引用不能直接引用右值，但是const左值引用可以引用右值
//    const int& rx1 = 10;
//    const string& rx4 = string("11111");
//
//    // 右值引用不能直接引用左值，但是右值引用可以引用move(左值)
//    int&& rrx1 = move(b);
//    int*&& rrx2 = move(p);
//    int&& rrx3 = move(*p);
//    string&& rrx4 = move(s);
//    string&& rrx5 = (string&&)s; // C风格强制转换，效果类似move
//
//
//    // 这里要注意的是，rr1的属性是左值，所以不能再被右值引用绑定，除非move一下
//    int& r6 = r1;
//    // int&& rrx6 = rr1; // 错误：无法将右值引用绑定到左值
//    int&& rrx6 = move(rr1); // 正确：使用move
//
//    // 3.3 引用延长生命周期示例
//    std::string s1 = "Test";
//    // std::string&& r1 = s1; // 错误：不能绑定到左值
//
//    const std::string& r8 = s1 + s1; // OK：到 const 的左值引用延长生存期
//    // r2 += "Test"; // 错误：不能通过到 const 的引用修改
//
//    std::string&& r9 = s1 + s1; // OK：右值引用延长生存期
//    r9 += "Test"; // OK：可以通过右值引用修改
//
//    return 0;
//}

//void f(int& x)
//{
//	std::cout << "左值引⽤重载 f(" << x << ")\n";
//} 
//void f(const int& x)
//{
//	std::cout << "到 const 的左值引⽤重载 f(" << x << ")\n";
//} 
//void f(int&& x)
//{
//	std::cout << "右值引⽤重载 f(" << x << ")\n";
//} 
//int main()
//{
//	int i = 1;
//	const int ci = 2;
//	f(i); // 调⽤ f(int&)
//	f(ci); // 调⽤ f(const int&)
//	f(3); // 调⽤ f(int&&)，如果没有 f(int&&) 重载则会调⽤ f(const int&)
//	f(std::move(i)); // 调⽤ f(int&&)
//	// 右值引⽤变量在⽤于表达式时是左值
//	int x = 10;
//	f(x); // 调⽤ f(int& x)
//	f(std::move(x)); // 调⽤ f(int&& x)
//	return 0;
//}

#define _CRT_SECURE_NO_WARNINGS 1
#include <iostream>
#include <cassert>
using namespace std;
namespace lsg
{
	class string
	{
	public:
		typedef char* iterator;
		typedef const char* const_iterator;
		iterator begin()
		{
			return _str;
		}

		iterator end()
		{
			return _str + _size;
		}

		const_iterator begin() const
		{
			return _str;
		}

		const_iterator end() const
		{
			return _str + _size;
		}

		string(const char* str = "")
			:_size(strlen(str))
			, _capacity(_size)
		{
			cout << "string(char* str)-构造" << endl;
			_str = new char[_capacity + 1];
			strcpy(_str, str);
		}

		void swap(string& tmp)
		{
			::swap(_str, tmp._str);
			::swap(_size, tmp._size);
			::swap(_capacity, tmp._capacity);
		}

		string(const string& s)
			:_str(nullptr)
		{
			cout << "string(const string& s) -- 拷贝构造" << endl;
			reserve(s._capacity);
			for (auto ch : s)
			{
				push_back(ch);
			}
		}

		// 移动构造
		string(string&& s)
		{
			cout << "string(string&& s) -- 移动构造" << endl;
			swap(s);
		}

		string& operator=(const string& s)
		{
			cout << "string& operator=(const string& s) -- 拷贝赋值" << endl;
			if (this != &s)
			{
				_str[0] = '\0';
				_size = 0;
				reserve(s._capacity);
				for (auto ch : s)
				{
					push_back(ch);
				}
			}
			return *this;
		}

		// 移动赋值
		string& operator=(string&& s)
		{
			cout << "string& operator=(string&& s) -- 移动赋值" << endl;
			swap(s);
			return *this;
		}

		~string()
		{
			if (_str)
			{
				cout << "~string() -- 析构" << endl;
				delete[] _str;
				_str = nullptr;
			}
		}

		char& operator[](size_t pos)
		{
			assert(pos < _size);
			return _str[pos];
		}

		void reserve(size_t n)
		{
			if (n > _capacity)
			{
				char* tmp = new char[n + 1];
				if (_str)
				{
					strcpy(tmp, _str);
					delete[] _str;
				}
				_str = tmp;
				_capacity = n;
			}
		}

		void push_back(char ch)
		{
			if (_size >= _capacity)
			{
				size_t newcapacity = _capacity == 0 ? 4 : _capacity * 2;
				reserve(newcapacity);
			}
			_str[_size] = ch;
			++_size;
			_str[_size] = '\0';
		}

		string& operator+=(char ch)
		{
			push_back(ch);
			return *this;
		}

		const char* c_str() const
		{
			return _str;
		}

		size_t size() const
		{
			return _size;
		}

	private:
		char* _str = nullptr;
		size_t _size = 0;
		size_t _capacity = 0;
	};
}
//int main()
//{
//	lsg::string s1("xxxxx");
//	// 拷⻉构造
//	lsg::string s2 = s1;
//	// 构造+移动构造，优化后直接构造
//	lsg::string s3 = lsg::string("yyyyy");
//	// 移动构造
//	lsg::string s4 = move(s1);
//	// 移动赋值
//	s4 = "1234";
//	cout << "******************************" << endl;
//
//	return 0;
//}
//lsg::string func()
//{
//	lsg::string str;
//	// ...内部逻辑
//	return str;
//}

//int main()
//{
//	lsg::string ret;
//	 ret = func();
//	return 0;
//}

//#include <list>
//#include "list.hpp"
//int main()
//{
//	std::list<lsg::string> lt;
//	
//	lsg::string s1("111111111111111111111");
//	lt.push_back(s1);
//	cout << "*************************" << endl;
//	
//	lt.push_back(lsg::string("22222222222222222222222222222"));
//	cout << "*************************" << endl;
//	
//	lt.push_back("3333333333333333333333333333");
//	cout << "*************************" << endl;
//	
//	lt.push_back(move(s1));
//	cout << "*************************" << endl;
//	
//	return 0;
//}


// #######################################################################
// 引用折叠
typedef int& lref;
typedef int&& rref;


//int main()
//{
//	int n = 0;
//	lref& r1 = n; // r1 的类型是 int&
//	lref&& r2 = n; // r2 的类型是 int&
//	rref& r3 = n; // r3 的类型是 int&
//	rref&& r4 = 1; // r4 的类型是 int&&
//	return 0;
//}


//// 由于引用折叠限定，f1实例化以后总是一个左值引用
template<class T>
void f1(T& x)
{
	// 全部是左值
	const int& a = x;
	cout << &a << endl;
	cout << &x << endl;
	cout << endl;
}

//int main()
//{
//	int n = 0;
//	// 没有折叠->实例化为void f1(int& x)
//	f1<int>(n);
//	//f1<int>(0); // 报错
//
//	// 折叠->实例化为void f1(int& x)
//	f1<int&>(n);
//	//f1<int&>(0); // 报错
//
//	// 折叠->实例化为void f1(int& x)
//	f1<int&&>(n);
//	//f1<int&&>(0); // 报错
//
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&>(n);
//	f1<const int&>(0);
//
//	// 折叠->实例化为void f1(const int& x)
//	f1<const int&&>(n);
//	f1<const int&&>(0);
//
//	return 0;
//}


////// 由于引用折叠限定，f2实例化后可以是左值引用，也可以是右值引用
////// 万能引用
//template<class T>
//void f2(T&& x)
//{}
//int main()
//{
//	int n = 0;
//	 // 没有折叠->实例化为void f2(int&& x)
//	//f2<int>(n); // 报错
//	f2<int>(0);
//
//	// 折叠->实例化为void f2(int& x)
//	f2<int&>(n);
//	//f2<int&>(0); // 报错
//
//	// 折叠->实例化为void f2(int&& x)
//	//f2<int&&>(n); // 报错
//	f2<int&&>(0);
//	return 0;
//}

//// 万能引用
//template<class T>
//void Function(T&& t)
//{
//	int a = 0;
//	T x = a;  // 这里可能有问题，取决于T的类型
//	//x++;     // 如果T是const类型，这里会编译错误
//
//	cout << &a << endl;
//	cout << &x << endl << endl;
//}
//
//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10); // 打印出地址不同 ✅
//
//	int a;
//	// a是左值，推导出T为int&，引用折叠后模板实例化为void Function(int& t)
//	Function(a); // 打印出地址相同 ✅
//
//	// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(std::move(a)); // 打印出地址不同 ✅
//
//	const int b = 8;
//	// b是const左值，推导出T为const int&，引用折叠后模板实例化为void Function(const int& t)
//	// Function内部T x = a; 即 const int x = a; 所以x++会编译报错
//	Function(b); // 打印出地址相同 ✅
//
//	// std::move(b)是const右值，推导出T为const int，模板实例化为void Function(const int&& t)
//	// Function内部T x = a; 即 const int x = a; 所以x++会编译报错
//	Function(std::move(b)); // 打印出地址不同 ✅
//
//	// c是具名的右值引用，它是一个左值
//	// 推导出T为int&，引用折叠后模板实例化为void Function(int& t)
//	int&& c = 10;
//	Function(c); // 打印出地址相同 ✅
//
//	return 0;
//}


// ####################################
//void Fun(int& x) { cout << "左值引用" << endl; }
//void Fun(const int& x) { cout << "const 左值引用" << endl; }
//void Fun(int&& x) { cout << "右值引用" << endl; }
//void Fun(const int&& x) { cout << "const 右值引用" << endl; }
//
//// 万能引用
//template<class T>
//void Function(T&& t)
//{
//	Fun(std::forward<T>(t)); // t的属性是左值
//}
//
//int main()
//{
//	// 10是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(10); // 右值
//
//	int a;
//	// a是左值，推导出T为int&，引用折叠，模板实例化为void Function(int& t)
//	Function(a); // 左值
//
//	// std::move(a)是右值，推导出T为int，模板实例化为void Function(int&& t)
//	Function(std::move(a)); // 右值
//
//	const int b = 8;
//	// a是左值，推导出T为const int&，引用折叠，模板实例化为void Function(const int& t)
//	Function(b);
//
//	// std::move(b)右值，推导出T为const int，模板实例化为void Function(const int&& t)
//	Function(std::move(b)); // const 右值
//
//	return 0;
//}
//

//template<class ...Args>
//void Print(Args&& ...args)
//{
//	cout << sizeof...(args) << endl;
//}

//int main()
//{
//	Print();
//	Print(1, "hello world");
//	Print(1, "hello world", 3.14);
//	Print(1, "hello world", "aaa", 2.2);
//	return 0;
//}
//// 原理1：编译本质这里会结合引用折叠规则实例化出以下四个函数
//void Print();
//void Print(int&& arg1, string&& arg2);
//void Print(int&& arg1, string&& arg2, double&& arg3);
//void Print(int&& arg1, string&& arg2, string&& arg3, double&& arg4);
//
//// 原理2：更本质去看没有可变参数模板，我们实现出这样的多个函数模板才能支持
//// 这里的功能，有了可变参数模板，我们进一步被解放，他是类型泛化基础
//// 上叠加数量变化，让我们泛型编程更灵活。
//void Print();
//
//template <class T1, class T2>
//void Print(T1&& arg1, T2&& arg2);
//template <class T1, class T2, class T3>
//void Print(T1&& arg1, T2&& arg2, T3&& arg3);
//template <class T1, class T2, class T3, class T4>
//void Print(T1&& arg1, T2&& arg2, T3&& arg3, T4&& arg4);

//void ShowList()
//{
//	cout << endl;
//}
//template<class T, class ...Args>
//void ShowList(T&& x, Args&&... args)
//{
//	cout << x << endl;
//	ShowList(forward<Args>(args)...);
//}
//
//template<class ...Args>
//void Print(Args&&... args)
//{
//	ShowList(args...);
//}

//template <class T>
//int GetArg(const T& x)
//{
//	cout << x << " ";
//	return 0;
//}
//
//template <class ...Args>
//void Arguments(Args... args)
//{}
////
//template <class ...Args>
//void Print(Args... args)
//{
//	// 注意GetArg必须返回或者到的对象，这样才能组成参数包给Arguments
//	// 参数包每个参数传给GetArg处理，处理以后返回值作为实参组合参数包传递给Arguments函数
//	Arguments(GetArg(args)...);
//
//	cout << endl;
//}
//// 本质可以理解为编译器编译时，包的扩展模式
//// 将上面的函数模板扩展实例化为下面的函数
////void Print(int x, string y, double z)
////{
////	Arguments(GetArg(x), GetArg(y), GetArg(z));
////}
//
//
//int main()
//{
//	double x = 2.2;
//	Print(); // 包里有0个参数
//	Print(1); // 包里有1个参数
//	Print(1, string("xxxxx")); // 包里有2个参数
//	Print(1, string("xxxxx"), x); // 包里有3个参数
//
//	return 0;
//}

/////////////////////////////////////////////////////////
//#include <list>
//int main()
//{
//	std::list<lsg::string> lt;
//	cout << "*********************************" << endl;
//
//	// 传左值，跟push_back一样，走拷贝构造
//	lsg::string s1("111111111111");
//	lt.emplace_back(s1);
//	lt.push_back(s1);
//	cout << "*********************************" << endl;
//
//	// 右值，跟push_back一样，走移动构造
//	lt.emplace_back(move(s1));
//	//lt.push_back(move(s1)); // 不能同时使用，把s1资源转移走了，下面不能再move了.分开测试
//	cout << "*********************************" << endl;
//
//	// 直接把构造string参数包往下传，直接用string参数包构造string
//	// 这里达到的效果是push_back做不到的
//	lt.emplace_back("111111111111");
//	lt.push_back("111111111111");
//	cout << "*********************************" << endl;
//
//	return 0;
//}

//#include "list.hpp"
//int main()
//{
//	lsg::list<std::pair<lsg::string, int>> lt1;
//	cout << "*********************************" << endl;
//
//	// 跟push_back一样
//	// 构造pair + 拷贝/移动构造pair到list的节点中data上
//	pair<lsg::string, int> kv("苹果", 1);
//	lt1.emplace_back(kv);
//	lt1.push_back(kv);
//	cout << "*********************************" << endl;
//
//	// 跟push_back一样
//	lt1.emplace_back(move(kv));
//	//lt1.push_back(move(kv));
//	cout << "*********************************" << endl;
//
//	// 直接把构造pair参数包往下传，直接⽤pair参数包构造pair
//	// 这⾥达到的效果是push_back做不到的
//	//lt1.emplace_back({ "苹果", 1 }); // 不能
//	lt1.emplace_back("苹果", 1 );
//	lt1.push_back({ "苹果", 1 });
//	//lt1.push_back( "苹果", 1 ); // err
//	cout << "*********************************" << endl;
//
//	return 0;
//}


// ######################

//class Person
//{
//public:
//	Person(const char* name = "xxxxxx", int age = 18)
//		:_name(name)
//		, _age(age)
//	{
//	}
//	// 没有资源要析构，偏偏加上
//	~Person()
//	{}
//
//private:
//	lsg::string _name;
//	int _age;
//};

class Person {
public:
	lsg::string name;

	Person(const lsg::string& n) : name(n) {}
	~Person() { /* ... 必要的清理逻辑 ... */ }

	// 显式要求编译器生成移动操作（C++11 onwards）
	Person(Person&&) = default;
	Person& operator=(Person&&) = default;

	// 同时，最好也显式定义或默认拷贝操作，避免潜在问题
	Person(const Person&) = default;
	Person& operator=(const Person&) = default;
};

//int main()
//{
//	Person s1("hello");
//	Person s2 = s1;
//	Person s3 = std::move(s1);
//
//	Person s4("8888");
//	s4 = std::move(s2);
//
//	return 0;
//}




///////////////////////////////////////////////////////////////
//#include<iostream>
//#include<functional>
//using namespace std;
//
//int f(int a, int b)
//{
//	return a + b;
//}
//
//struct Functor
//{
//public:
//	int operator() (int a, int b)
//	{
//		return a + b;
//	}
//};
//
//class Plus
//{
//public:
//	Plus(int n = 10)
//		:_n(n)
//	{}
//
//	static int plusi(int a, int b)
//	{
//		return a + b;
//	}
//
//	double plusd(double a, double b)
//	{
//		return (a + b) * _n;
//	}
//private:
//	int _n;
//};
//
//int main()
//{
//	// 包装各种可调用对象
//	function<int(int, int)> f1 = f;
//	function<int(int, int)> f2 = Functor();
//	function<int(int, int)> f3 = [](int a, int b) {return a + b; };
//	cout << f1(1, 1) << endl;
//	cout << f2(1, 1) << endl;
//	cout << f3(1, 1) << endl;
//
//	// 包装静态成员函数
//	// 成员函数要指定类域并且前面加&才能获取地址
//	function<int(int, int)> f4 = &Plus::plusi;
//	cout << f4(1, 1) << endl;
//	// 包装成员函数要需要注意this指针。
//	function<double(Plus*, double, double)> f5 = &Plus::plusd; 
//	Plus ps;
//	cout << f5(&ps, 1, 1) << endl;
//
//	function<double(Plus&, double, double)> f6 = &Plus::plusd;
//	cout << f6(ps, 1, 1) << endl;
//	
//	function<double(Plus&&, double, double)> f7 = &Plus::plusd;
//	cout << f7(Plus(), 1, 1) << endl;
//
//	return 0;
//}



////////////////////////
////#include <functional>
////using placeholders::_1;
////using placeholders::_2;
////using placeholders::_3;
////
////int Sub(int a, int b)
////{
////	return (a - b) * 10;
////}
////
////int SubX(int a, int b, int c)
////{
////	return (a - b - c) * 10;
////}
////
////int main()
////{
////	// std::function 的类型由 最终调用时需要的参数类型和返回类型 决定,返回类型就是被绑定函数的返回类型
////	// 情况1：绑定所有占位符，需要2个int参数
////	function<int(int, int)> f1 = bind(Sub, _1, _2);
////
////	// 情况2：固定第一个参数，只需要1个int参数
////	function<int(int)> f2 = bind(Sub, 100, _1);  // Sub(100, x)
////
////	// 情况3：固定第二个参数，只需要1个int参数  
////	function<int(int)> f3 = bind(Sub, _1, 5);    // Sub(x, 5)
////
////	// 情况4：固定所有参数，不需要参数
////	function<int()> f4 = bind(Sub, 100, 5);      // Sub(100, 5)
////
////	// 如果不想写，直接写auto ,ok
////	auto sub1 = bind(Sub, _1, _2);
////
////	cout << sub1(10, 5) << endl;
////
////	// bind 本质返回的一个仿函数对象
////	// 调整参数顺序（不常用）
////	// _1代表第一个实参
////	// _2代表第二个实参
////	// ...
////	// 调整参数熟顺序
////	auto sub2 = bind(Sub, _2, _1);
////	cout << sub2(10, 5) << endl;
////
////	// 调整参数个数
////	// 绑死a
////	auto sub3 = bind(Sub, 100, _1);
////	cout << sub3(5) << endl;
////
////	// 绑死b
////	auto sub4 = bind(Sub, _1, 100);
////	cout << sub4(5) << endl;
////
////	// 分别绑死第123个参数
////	auto sub5 = bind(SubX, 100, _1, _2);
////	cout << sub5(5, 1) << endl;
////	auto sub6 = bind(SubX, _1, 100, _2);
////	cout << sub6(5, 1) << endl;
////	auto sub7 = bind(SubX, _1, _2, 100);
////	cout << sub7(5, 1) << endl;
////
////	return 0;
////}
//
//#include <functional>
//using placeholders::_1;
//using placeholders::_2;
//using placeholders::_3;
//class Plus
//{
//public:
//	static int plusi(int a, int b)
//	{
//		return a + b;
//	}
//	double plusd(double a, double b)
//	{
//		return a + b;
//	}
//};
//
//
// //成员函数对象进行绑死，就不需要每次都传递了
//int main()
//{
//	function<double(Plus&&, double, double)> f6 = &Plus::plusd;
//	Plus pd;
//	cout << f6(move(pd), 1.1, 1.1) << endl;
//	cout << f6(Plus(), 1.1, 1.1) << endl;
//
//	// bind一般用于，绑死一些固定参数
//	function<double(double, double)> f7 = bind(&Plus::plusd, Plus(), _1, _2); // 直接把plused这个方法绑死，参数类型就是plused的类型。
//	cout << f7(1.1, 1.1) << endl;
//	return 0;
//}


#include <unordered_map>
#include <functional>
int main()
{
	unordered_map<string, function<int(int, int)>> operFuncMap =
	{
		{"+", [](int a, int b) {return a + b; }},
		{"-", [](int a, int b) {return a - b; }},
		{"*", [](int a, int b) {return a * b; }},
		{"/", [](int a, int b) {return a / b; }},
		{"^", [](int a, int b) {return a ^ b; }},
		{"&", [](int a, int b) {return a & b; }}
	};

	std::cout << operFuncMap["+"](10, 20) << std::endl;
	std::cout << operFuncMap["-"](10, 20) << std::endl;
	std::cout << operFuncMap["*"](10, 20) << std::endl;
	return 0;
}
